/*
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
 */
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sun.org.apache.xerces.internal.xinclude;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;

/**
 * This class is duplicated for each subpackage so keep it in sync.
 * It is package private and therefore is not exposed as part of any API.
 *
 * @xerces.internal
 */
final class SecuritySupport {

    private static final SecuritySupport securitySupport = new SecuritySupport();

    /**
     * Return an instance of this class.
     */
    static SecuritySupport getInstance() {
        return securitySupport;
    }

    ClassLoader getContextClassLoader() {
        return (ClassLoader)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        ClassLoader cl = null;
                        try {
                            cl = Thread.currentThread().getContextClassLoader();
                        } catch (SecurityException ex) {
                        }
                        return cl;
                    }
                });
    }

    ClassLoader getSystemClassLoader() {
        return (ClassLoader)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        ClassLoader cl = null;
                        try {
                            cl = ClassLoader.getSystemClassLoader();
                        } catch (SecurityException ex) {
                        }
                        return cl;
                    }
                });
    }

    ClassLoader getParentClassLoader(final ClassLoader cl) {
        return (ClassLoader)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        ClassLoader parent = null;
                        try {
                            parent = cl.getParent();
                        } catch (SecurityException ex) {
                        }

                        // eliminate loops in case of the boot
                        // ClassLoader returning itself as a parent
                        return (parent == cl) ? null : parent;
                    }
                });
    }

    String getSystemProperty(final String propName) {
        return (String)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        return System.getProperty(propName);
                    }
                });
    }

    FileInputStream getFileInputStream(final File file)
            throws FileNotFoundException {
        try {
            return (FileInputStream)
                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws FileNotFoundException {
                            return new FileInputStream(file);
                        }
                    });
        } catch (PrivilegedActionException e) {
            throw (FileNotFoundException) e.getException();
        }
    }

    InputStream getResourceAsStream(final ClassLoader cl,
                                    final String name) {
        return (InputStream)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        InputStream ris;
                        if (cl == null) {
                            ris = ClassLoader.getSystemResourceAsStream(name);
                        } else {
                            ris = cl.getResourceAsStream(name);
                        }
                        return ris;
                    }
                });
    }

    boolean getFileExists(final File f) {
        return ((Boolean)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        return f.exists();
                    }
                })).booleanValue();
    }

    long getLastModified(final File f) {
        return ((Long)
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        return f.lastModified();
                    }
                })).longValue();
    }

    private SecuritySupport() {
    }
}
